package com.jbtrader;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;

import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.DropMode;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ListModel;
import javax.swing.SpinnerDateModel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.miginfocom.layout.AC;
import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;

public class UserRegistration extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JList m_allBrandsList;
    private JList m_selectedBrandsList;
    final Font LABELS_FONT = UIManager.getDefaults().getFont("Label.font").deriveFont(Font.BOLD);

    public UserRegistration() {
        super("User Registration");
        
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.setName("registration.tabs");
        tabbedPane.addTab("Account Info", getAccountInfoPanel());
        tabbedPane.addTab("Jukebox Preferences", getJukeboxPreferencesPanel());
        tabbedPane.addTab("Terms and Conditions", getTermsAndConditionsPanel());

        getContentPane().add(tabbedPane);
    }

    private Component getTermsAndConditionsPanel() {
        JPanel termsPanel = new JPanel();
        termsPanel.setLayout(new MigLayout(new LC().insets(
                "10px", "15px", "5px", "5px").wrapAfter(2),
                new AC().growPrio(50, 0, 1),
                new AC().noGrid()));
        JLabel termsLabel = new JLabel("Terms of Use:");
        termsLabel.setFont(LABELS_FONT);
        termsPanel.add(termsLabel, "span 2, wrap, gapbottom 10");
        termsLabel.setDisplayedMnemonic('U');

        JTextArea termsArea = new JTextArea("The verbocious stuff goes here ...");
        termsLabel.setLabelFor(termsArea);
        termsPanel.add(termsArea, "span 2, w :300:400, h :300:400, wrap, gapbottom 20");

        ButtonGroup bg = new ButtonGroup();
        JRadioButton agreeButton = new JRadioButton("I agree with the terms and conditions");
        agreeButton.setMnemonic('A');
        bg.add(agreeButton);
        agreeButton.setName("agree.button");
        JRadioButton notAgreeButton = new JRadioButton("I do NOT agree with these terms");
        notAgreeButton.setMnemonic('N');
        bg.add(notAgreeButton);
        notAgreeButton.setName("not.agree.button");

        termsPanel.add(agreeButton, "span 2, wrap, gapbottom 8");
        termsPanel.add(notAgreeButton, "span 2, wrap, gapbottom 10");

        JButton registerButton = new JButton("Register");
        registerButton.setMnemonic('R');
        termsPanel.add(registerButton);
        registerButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Registered");
            }
        });

        JButton cancelButton = new JButton("Cancel");
        cancelButton.setMnemonic('C');
        termsPanel.add(cancelButton);

        return termsPanel;
    }

    private JPanel getAccountInfoPanel() {
        JPanel accountInfoContentsPanel = new JPanel();

        accountInfoContentsPanel.setLayout(new MigLayout(new LC().insets(
                "10px", "15px", "5px", "5px").wrapAfter(3), new AC().growPrio(
                50, 0, 1, 2), new AC().noGrid()));

        accountInfoContentsPanel.add(new JLabel(), "width 120!, span 3, wrap");
        USERNAME:
        {
            JLabel userLabel = new JLabel("Username:");
            userLabel.setFont(LABELS_FONT);
            accountInfoContentsPanel.add(userLabel, "width 100!, gapright 30");
            userLabel.setDisplayedMnemonic('U');

            JTextField userField = new JTextField();
            userField.setName("user.field");
            userLabel.setLabelFor(userField);
            accountInfoContentsPanel.add(userField,
                    "width 100:200:300, span 2, wrap");
        }

        PASSWORD:
        {
            JLabel passwordLabel = new JLabel("Password:");
            passwordLabel.setFont(LABELS_FONT);
            accountInfoContentsPanel.add(passwordLabel,
                    "width 100!, gapright 30");
            passwordLabel.setDisplayedMnemonic('P');

            JPasswordField passwordField = new JPasswordField();
            passwordField.setName("password.field");
            passwordLabel.setLabelFor(passwordField);
            accountInfoContentsPanel.add(passwordField,
                    "width 100:200:300, span 2, wrap");
        }

        RETYPE_PASSWORD:
        {
            JLabel retypePasswordLabel = new JLabel("Re-type Password:");
            retypePasswordLabel.setFont(LABELS_FONT);
            retypePasswordLabel.setDisplayedMnemonic('R');
            accountInfoContentsPanel.add(retypePasswordLabel, "width 120!");

            JPasswordField retypePasswordField = new JPasswordField();
            retypePasswordField.setName("retype.password.field");
            retypePasswordLabel.setLabelFor(retypePasswordField);
            accountInfoContentsPanel.add(retypePasswordField,
                    "width 100:200:300, span 2, wrap");
        }

        ACCOUNT_VISIBILITY:
        {
            JLabel accountVisibilityLabel = new JLabel("Account Visibility:");
            accountVisibilityLabel.setFont(LABELS_FONT);
            accountVisibilityLabel.setDisplayedMnemonic('A');
            accountInfoContentsPanel.add(accountVisibilityLabel,
                    "wrap, gaptop 30");

            ButtonGroup visibilityBG = new ButtonGroup();
            JRadioButton publicButton = new JRadioButton("Public");
            publicButton.setName("public.button");
            publicButton.setMnemonic('b');
            accountInfoContentsPanel.add(publicButton, "gaptop 10");
            visibilityBG.add(publicButton);

            JRadioButton groupButton = new JRadioButton("Group");
            groupButton.setName("group.button");
            groupButton.setMnemonic('G');
            accountInfoContentsPanel.add(groupButton, "gapleft 30");
            visibilityBG.add(groupButton);

            JRadioButton privateButton = new JRadioButton("Private");
            privateButton.setName("private.button");
            privateButton.setMnemonic('v');
            accountInfoContentsPanel.add(privateButton, "gapleft 30, wrap");
            visibilityBG.add(privateButton);
        }

        REGISTRATION_PREEFERENCES:
        {
            JLabel registrationPreferencesLabel = new JLabel(
                    "Registration Preferences:");
            registrationPreferencesLabel.setFont(LABELS_FONT);
            registrationPreferencesLabel.setDisplayedMnemonic('P');
            accountInfoContentsPanel.add(registrationPreferencesLabel,
                    "wrap, gaptop 30");

            JCheckBox subscribeToNewsletter = new JCheckBox(
                    "Subscribe to our newsletter:");
            subscribeToNewsletter.setName("subscribe.button");
            subscribeToNewsletter.setMnemonic('n');
            registrationPreferencesLabel.setLabelFor(subscribeToNewsletter);
            accountInfoContentsPanel.add(subscribeToNewsletter,
                    "gaptop 10, wrap");
        }

        USER_TYPE:
        {
            JLabel userTypeLabel = new JLabel("User Type:");
            userTypeLabel.setFont(LABELS_FONT);
            userTypeLabel.setDisplayedMnemonic('T');
            accountInfoContentsPanel.add(userTypeLabel, "wrap, gaptop 30");

            JComboBox userTypeCombo = new JComboBox(new String[]{"Buyer",
                        "Seller", "Both"
                    });
            userTypeCombo.setName("user.type.combo");
            userTypeLabel.setLabelFor(userTypeCombo);
            accountInfoContentsPanel.add(userTypeCombo, "gaptop 10");
        }

        return accountInfoContentsPanel;
    }

    private JPanel getJukeboxPreferencesPanel() {
        JPanel jukeboxPreferencesPanel = new JPanel();

        jukeboxPreferencesPanel.setLayout(new MigLayout(new LC().insets("10px",
                "15px", "5px", "5px").wrapAfter(3), new AC().growPrio(50, 0, 1,
                2), new AC().growPrio(50, 0, 1, 2).count(10).noGrid()));
        JLabel brandSelector = new JLabel("Select Jukebox Brands:");
        brandSelector.setFont(LABELS_FONT);
        jukeboxPreferencesPanel.add(brandSelector, "gapbottom 10, wrap");
        brandSelector.setDisplayedMnemonic('B');

        m_allBrandsList = new JList(getJukeboxListModel());
        m_allBrandsList.setDragEnabled(true);
        m_allBrandsList.setName("all.brands.list");
        brandSelector.setLabelFor(m_allBrandsList);
        jukeboxPreferencesPanel.add(new JScrollPane(m_allBrandsList),
                "w 100!, h 100:250:300");

        JPanel buttonPanel = new JPanel(new BorderLayout());
        JButton selectItem = new JButton(">>");
        selectItem.setName("select.brand");
        buttonPanel.add(selectItem, BorderLayout.NORTH);

        JButton unselectItem = new JButton("<<");
        unselectItem.setName("unselect.brand");
        buttonPanel.add(unselectItem, BorderLayout.SOUTH);
        jukeboxPreferencesPanel.add(buttonPanel, "gapleft 40");

        m_selectedBrandsList = new JList(new DefaultListModel());
        m_selectedBrandsList.setName("selected.brands.list");
        jukeboxPreferencesPanel.add(new JScrollPane(m_selectedBrandsList),
                "gapleft 40, w 100!, h 100:250:300");
        m_selectedBrandsList.setDragEnabled(true);

        JLabel yearSelectorLabel = new JLabel("Select Preferred Year Range:");
        yearSelectorLabel.setFont(LABELS_FONT);
        jukeboxPreferencesPanel.add(yearSelectorLabel,
                "gaptop 15, gapbottom 10, span 3, wrap");

        selectItem.addActionListener(new ListSelectionActionListener(
                m_allBrandsList, m_selectedBrandsList));
        unselectItem.addActionListener(new ListSelectionActionListener(
                m_selectedBrandsList, m_allBrandsList));

        TransferHandler transferHandler = new ListTransferHandler();
        m_allBrandsList.setTransferHandler(transferHandler);
        m_selectedBrandsList.setTransferHandler(transferHandler);
        m_allBrandsList.setDropMode(DropMode.ON_OR_INSERT);
        m_selectedBrandsList.setDropMode(DropMode.ON_OR_INSERT);
        setMappings(m_allBrandsList);
        setMappings(m_selectedBrandsList);

        JPanel fromPanel = new JPanel();
        JLabel fromYearSelectorLabel = new JLabel("From:");
        fromYearSelectorLabel.setFont(LABELS_FONT);
        fromYearSelectorLabel.setDisplayedMnemonic('F');
        fromPanel.add(fromYearSelectorLabel);
        JSpinner fromSpinner = makeYearSpinner(1927);
        fromSpinner.setName("from.spinner");
        fromYearSelectorLabel.setLabelFor(fromSpinner);
        fromPanel.add(fromSpinner);
        jukeboxPreferencesPanel.add(fromPanel, "gapright 20, span 2");

        JPanel toPanel = new JPanel();
        JLabel toYearSelectorLabel = new JLabel("To:");
        toYearSelectorLabel.setFont(LABELS_FONT);
        toYearSelectorLabel.setDisplayedMnemonic('T');
        toPanel.add(toYearSelectorLabel);
        JSpinner toSpinner = makeYearSpinner(2008);
        toSpinner.setName("to.spinner");
        toYearSelectorLabel.setLabelFor(toSpinner);
        toPanel.add(toSpinner);
        jukeboxPreferencesPanel.add(toPanel, "span 1, wrap");

        // Adding budget
        JLabel budgetLimitLabel = new JLabel("Select Budget Limit or Press ");
        budgetLimitLabel.setFont(LABELS_FONT);
        budgetLimitLabel.setDisplayedMnemonic('L');
        jukeboxPreferencesPanel.add(budgetLimitLabel,
                "gaptop 15,  gapbottom 10, span 2");
        final JToggleButton dnmButton = new JToggleButton("Does not matter");
        dnmButton.setMnemonic('M');
        jukeboxPreferencesPanel.add(dnmButton, "span 1, wrap");
        dnmButton.setName("budget.dnm.button");
        final JSlider budgetSelector = new JSlider();
        budgetSelector.setName("budget.selector.slider");
        budgetSelector.setMaximum(20000);
        budgetSelector.setMinimum(0);
        budgetSelector.setMajorTickSpacing(4000);
        budgetSelector.setMinorTickSpacing(500);
        jukeboxPreferencesPanel.add(budgetSelector, "span 2");
        final JLabel budgetLabel = new JLabel("$0");
        jukeboxPreferencesPanel.add(budgetLabel, "span 1, wrap");
        budgetSelector.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                budgetLabel.setText("$" + ((JSlider) e.getSource()).getValue());
            }
        });
        dnmButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                budgetSelector.setEnabled(!dnmButton.isSelected());
            }
        });

        return jukeboxPreferencesPanel;
    }

    /**
     * Add the cut/copy/paste actions to the action map.
     */
    private static void setMappings(JList list) {
        ActionMap map = list.getActionMap();
        map.put(TransferHandler.getCutAction().getValue(Action.NAME),
                TransferHandler.getCutAction());
        map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
                TransferHandler.getCopyAction());
        map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
                TransferHandler.getPasteAction());

    }

    private static class ListSelectionActionListener implements ActionListener {

        final JList m_source;
        final JList m_dest;

        ListSelectionActionListener(JList source, JList dest) {
            m_source = source;
            m_dest = dest;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Object selections[] = m_source.getSelectedValues();
            if (selections != null && selections.length > 0) {
                for (Object selection : selections) {
                    ((DefaultListModel) m_dest.getModel()).addElement(selection);
                    ((DefaultListModel) m_source.getModel()).removeElement(selection);
                }
            }
        }
    };

    private static JSpinner makeYearSpinner(int year) {
        JSpinner spinner = new JSpinner();
        spinner.setModel(new SpinnerDateModel(makeYearOnlyDate(year),
                makeYearOnlyDate(1926), makeYearOnlyDate(2008), Calendar.YEAR));
        spinner.setEditor(new JSpinner.DateEditor(spinner, "yyyy"));
        return spinner;
    }

    private static Date makeYearOnlyDate(int year) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        return c.getTime();
    }

    private static ListModel getJukeboxListModel() {
        DefaultListModel model = new DefaultListModel();
        model.addElement("Wurlitzer");
        model.addElement("Seeburg");
        model.addElement("Rock-ola");
        model.addElement("Rowe AMI");
        model.addElement("Mills");
        model.addElement("Evans");
        model.addElement("Gabel");
        model.addElement("United");
        model.addElement("Capehart");
        model.addElement("Packard");
        return model;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (UnsupportedLookAndFeelException e) {
                    // handle exception
                } catch (ClassNotFoundException e) {
                    // handle exception
                } catch (InstantiationException e) {
                    // handle exception
                } catch (IllegalAccessException e) {
                    // handle exception
                }
                UserRegistration ur = new UserRegistration();
                ur.setVisible(true);
                ur.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                ur.setSize(400, 600);
            // ur.setResizable(false);
            }
        });

    }
}
